/**
 * Copyright (c) 2018-2023, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 *
 * Contains: 
 *
 * Change Logs:
 * Date           Author            Notes
 * 2023-07-07     Shiroko           Init
 */
#ifndef __DRIVERS_VIRTIO_VIRTIO_BLK_H__
#define __DRIVERS_VIRTIO_VIRTIO_BLK_H__

#include "nxos.h"

#ifdef CONFIG_NX_DRIVER_VIRTIO_BLK

struct VirtioBLKDeviceConfig
{
    NX_U64 capacity;
    NX_U32 size_max;
    NX_U32 seg_max;
    struct virtio_blk_geometry
    {
        NX_U16 cylinders;
        NX_U8  heads;
        NX_U8  sectors;
    }      geometry;
    NX_U32 blk_size;
    struct virtio_blk_topology
    {
        // # of logical blocks per physical block (log2)
        NX_U8  physical_block_exp;
        // offset of first aligned logical block
        NX_U8  alignment_offset;
        // suggested minimum I/O size in blocks
        NX_U16 min_io_size;
        // optimal (suggested maximum) I/O size in blocks
        NX_U32 opt_io_size;
    }      topology;
    NX_U8  writeback;
    NX_U8  unused0;
    NX_U16 num_queues;
    NX_U32 max_discard_sectors;
    NX_U32 max_discard_seg;
    NX_U32 discard_sector_alignment;
    NX_U32 max_write_zeroes_sectors;
    NX_U32 max_write_zeroes_seg;
    NX_U8  write_zeroes_may_unmap;
    NX_U8  unused1[3];
    NX_U32 max_secure_erase_sectors;
    NX_U32 max_secure_erase_seg;
    NX_U32 secure_erase_sector_alignment;
};
typedef struct VirtioBLKDeviceConfig VirtioBLKDeviceConfig;

// Modern interface
#define VIRTIO_BLK_FEATURE_SIZE_MAX     (1<<1)
#define VIRTIO_BLK_FEATURE_SEG_MAX      (1<<2)
#define VIRTIO_BLK_FEATURE_GEOMETRY     (1<<4)
#define VIRTIO_BLK_FEATURE_RO           (1<<5)  /* Read-only */
#define VIRTIO_BLK_FEATURE_BLK_SIZE     (1<<6)
#define VIRTIO_BLK_FEATURE_FLUSH        (1<<9)
#define VIRTIO_BLK_FEATURE_TOPOLOGY     (1<<10)
#define VIRTIO_BLK_FEATURE_CONFIG_WCE   (1<<11)
#define VIRTIO_BLK_FEATURE_MQ           (1<<12) /* Multi-queue */
#define VIRTIO_BLK_FEATURE_DISCARD      (1<<13)
#define VIRTIO_BLK_FEATURE_WRITE_ZEROES (1<<14)
#define VIRTIO_BLK_FEATURE_LIFETIME     (1<<15)
#define VIRTIO_BLK_FEATURE_SECURE_ERASE (1<<16)
// Legacy interface
#define VIRTIO_BLK_FEATURE_BARRIER      (1<<0)
#define VIRTIO_BLK_FEATURE_SCSI         (1<<7)


#define VIRTIO_BLK_TYPE_IN           0
#define VIRTIO_BLK_TYPE_OUT          1
#define VIRTIO_BLK_TYPE_FLUSH        4
#define VIRTIO_BLK_TYPE_GET_ID       8
#define VIRTIO_BLK_TYPE_GET_LIFETIME 10
#define VIRTIO_BLK_TYPE_DISCARD      11
#define VIRTIO_BLK_TYPE_WRITE_ZEROES 13
#define VIRTIO_BLK_TYPE_SECURE_ERASE   14

#define VIRTIO_BLK_SECTOR_SIZE  512

struct VirtioBLKRequestPart1
{
    NX_U32 type;
    NX_U32 reserved;
    NX_U64 sector;
    // Part2: data
    // Part3: status
};
typedef struct VirtioBLKRequestPart1 VirtioBLKRequestPart1;

/*
 * Public interface
 */
#define VIRTIO_BLK_FLAGS_READ_ONLY 1

#endif // CONFIG_NX_DRIVER_VIRTIO_BLK
#endif // __DRIVERS_VIRTIO_VIRTIO_BLK_H__
